home *** CD-ROM | disk | FTP | other *** search
Text File | 1992-11-18 | 44.8 KB | 1,300 lines | [TEXT/MPS ] |
- C.S.M.P. Digest Sat, 21 Mar 92 Volume 1 : Issue 27
-
- Today's Topics:
-
- Finding available fonts
- Q: Eliminating clicks when playing sampled sounds
- Software Locking for Word 4D
- DirectorOwner owns DialogDirector and crashes (Think C/TCL)
-
-
- The Comp.Sys.Mac.Programmer Digest is moderated by Michael A. Kelly.
-
- These digests are available (by using FTP, account anonymous, your email
- address as password) in the pub/mac/csmp-digest directory on ftp.cs.uoregon.
- edu (try skinner.cs.uoregon.edu if that doesn't work). This is also the home
- of the comp.sys.mac.programmer Frequently Asked Questions list.
-
- These digests are also available via email. Just send a note saying that you
- want to be on the digest mailing list to mkelly@cs.uoregon.edu, and you will
- automatically receive each new digest as it is created.
-
- The articles in these digests are taken directly from comp.sys.mac.programmer.
- They are not edited; all articles included in this digest are in their original
- posted form. The only articles that are -not- included in these digests are
- those which didn't receive any replies (except those that give information
- rather than ask a question). All replies to each article are concatenated
- onto the original article in the order in which they were received. Article
- threads are not added to the digests until the last article added to the
- thread is at least one month old (this is to ensure that the thread is dead
- before adding it to the digests).
-
- Send administrative mail to mkelly@cs.uoregon.edu.
-
- -------------------------------------------------------
-
- From: jpugh@apple.com (Jon Pugh)
- Subject: Finding available fonts
- Date: 20 Jan 92 21:17:23 GMT
- Organization: Apple Co.
-
- In article <1992Jan17.150406@wilbury.cs.Virginia.EDU>, rad2r@wilbury.cs.Virginia.EDU (Robert DeLine) writes:
- >
- > What I'm looking for is a way from within a program to find out
- > which font families are currently available. I've noticed that
- > many applications look up this information, so I know it must be
- > possible. Perhaps I should mention that the final destination for
- > this list is not a menu. This is easy, right?
- >
- > Rob DeLine
- > deline@Virginia.EDU
-
- Fonts are stored in several resources. In theory every font family should have a FOND
- resource and a list of them would suffice. The actual font faces are stored as FONT and
- NFNT resources with TrueType outlines stored as sfnt resources.
-
- Good luck,
-
- Jon
-
-
-
- - -------------------------
-
- From: wdh@well.sf.ca.us (Bill Hofmann)
- Subject: Finding available fonts
- Date: 28 Jan 92 17:39:12 GMT
- Organization: Flashpoint
-
- jpugh@apple.com (Jon Pugh) writes:
-
- >In article <1992Jan17.150406@wilbury.cs.Virginia.EDU>, rad2r@wilbury.cs.Virginia.EDU (Robert DeLine) writes:
- >>
- >> What I'm looking for is a way from within a program to find out
- >> which font families are currently available. I've noticed that
- >> many applications look up this information, so I know it must be
- >> possible. Perhaps I should mention that the final destination for
- >> this list is not a menu. This is easy, right?
- >Fonts are stored in several resources. In theory every font family should have a FOND
- >resource and a list of them would suffice. The actual font faces are stored as FONT and
- >NFNT resources with TrueType outlines stored as sfnt resources.
- >Good luck,
- >Jon
-
- Actually, the easiest, AND recommended, way to get the fonts in the system
- is to create a menu. So:
- {
- MenuHandle faux;
- Str255 fontName;
- short fontNum;
- short i, numFonts;
-
- faux = NewMenu("\pFaunt");
- AddResMenu(faux, 'FONT'); /* of course, check for NIL */
- numFonts = CountMItems(faux);
- for (i = 1; i <= numFonts; i++)
- {
- GetItem(faux, i, fontName);
- GetFNum(fontName, &fontNum);
- /* do what you will with fontNum */
- }
- DisposMenu(faux);
- }
- The reason is that every time they muck with the system they'll add and
- modify font resource types, but they HAVE to guarantee that AddResMenu
- will always work, so your program will ALWAYS get the current list of
- fonts, be they bitmap FONT, bitmap NFNT, sfnt, or whatever.
-
- -Bill Hofmann
-
-
-
- - -------------------------
-
- From: nerm@apple.com (Dean Yu)
- Subject: Finding available fonts
- Date: 31 Jan 92 23:21:55 GMT
- Organization: Apple Computer, Inc.
-
- In article <29685@well.sf.ca.us>, wdh@well.sf.ca.us (Bill Hofmann) writes:
- >
- > jpugh@apple.com (Jon Pugh) writes:
- >
- > >In article <1992Jan17.150406@wilbury.cs.Virginia.EDU>, rad2r@wilbury.cs.Virginia.EDU (Robert DeLine) writes:
- > >>
- > >> What I'm looking for is a way from within a program to find out
- > >> which font families are currently available. I've noticed that
- > >> many applications look up this information, so I know it must be
- > >> possible. Perhaps I should mention that the final destination for
- > >> this list is not a menu. This is easy, right?
- > >Fonts are stored in several resources. In theory every font family should have a FOND
- > >resource and a list of them would suffice. The actual font faces are stored as FONT and
- > >NFNT resources with TrueType outlines stored as sfnt resources.
- > >Good luck,
- > >Jon
- >
- > Actually, the easiest, AND recommended, way to get the fonts in the system
- > is to create a menu. So:
- > {
- > MenuHandle faux;
- > Str255 fontName;
- > short fontNum;
- > short i, numFonts;
- >
- > faux = NewMenu("\pFaunt");
- > AddResMenu(faux, 'FONT'); /* of course, check for NIL */
- ^^^^
-
- Just to be nitpicky, you should use AddResMenu(faux, 'FOND') to access
- available fonts through the font families they belong to.
-
- -- Dean Yu
- Blue Meanie, Negative Ethnic Role Model, Window Cleaner,
- Skanky Hack Consultant, etc.
- Apple Computer, Inc.
- blah blah blah blah blah...
-
-
-
- - -------------------------
-
- From: wdh@well.sf.ca.us (Bill Hofmann)
- Subject: Finding available fonts
- Date: 28 Jan 92 17:39:12 GMT
- Organization: Flashpoint
-
- jpugh@apple.com (Jon Pugh) writes:
-
- >In article <1992Jan17.150406@wilbury.cs.Virginia.EDU>, rad2r@wilbury.cs.Virginia.EDU (Robert DeLine) writes:
- >>
- >> What I'm looking for is a way from within a program to find out
- >> which font families are currently available. I've noticed that
- >> many applications look up this information, so I know it must be
- >> possible. Perhaps I should mention that the final destination for
- >> this list is not a menu. This is easy, right?
- >Fonts are stored in several resources. In theory every font family should have a FOND
- >resource and a list of them would suffice. The actual font faces are stored as FONT and
- >NFNT resources with TrueType outlines stored as sfnt resources.
- >Good luck,
- >Jon
-
- Actually, the easiest, AND recommended, way to get the fonts in the system
- is to create a menu. So:
- {
- MenuHandle faux;
- Str255 fontName;
- short fontNum;
- short i, numFonts;
-
- faux = NewMenu("\pFaunt");
- AddResMenu(faux, 'FONT'); /* of course, check for NIL */
- numFonts = CountMItems(faux);
- for (i = 1; i <= numFonts; i++)
- {
- GetItem(faux, i, fontName);
- GetFNum(fontName, &fontNum);
- /* do what you will with fontNum */
- }
- DisposMenu(faux);
- }
- The reason is that every time they muck with the system they'll add and
- modify font resource types, but they HAVE to guarantee that AddResMenu
- will always work, so your program will ALWAYS get the current list of
- fonts, be they bitmap FONT, bitmap NFNT, sfnt, or whatever.
-
- -Bill Hofmann
-
-
-
- - -------------------------
-
- From: nerm@apple.com (Dean Yu)
- Subject: Finding available fonts
- Date: 31 Jan 92 23:21:55 GMT
- Organization: Apple Computer, Inc.
-
- In article <29685@well.sf.ca.us>, wdh@well.sf.ca.us (Bill Hofmann) writes:
- >
- > jpugh@apple.com (Jon Pugh) writes:
- >
- > >In article <1992Jan17.150406@wilbury.cs.Virginia.EDU>, rad2r@wilbury.cs.Virginia.EDU (Robert DeLine) writes:
- > >>
- > >> What I'm looking for is a way from within a program to find out
- > >> which font families are currently available. I've noticed that
- > >> many applications look up this information, so I know it must be
- > >> possible. Perhaps I should mention that the final destination for
- > >> this list is not a menu. This is easy, right?
- > >Fonts are stored in several resources. In theory every font family should have a FOND
- > >resource and a list of them would suffice. The actual font faces are stored as FONT and
- > >NFNT resources with TrueType outlines stored as sfnt resources.
- > >Good luck,
- > >Jon
- >
- > Actually, the easiest, AND recommended, way to get the fonts in the system
- > is to create a menu. So:
- > {
- > MenuHandle faux;
- > Str255 fontName;
- > short fontNum;
- > short i, numFonts;
- >
- > faux = NewMenu("\pFaunt");
- > AddResMenu(faux, 'FONT'); /* of course, check for NIL */
- ^^^^
-
- Just to be nitpicky, you should use AddResMenu(faux, 'FOND') to access
- available fonts through the font families they belong to.
-
- -- Dean Yu
- Blue Meanie, Negative Ethnic Role Model, Window Cleaner,
- Skanky Hack Consultant, etc.
- Apple Computer, Inc.
- blah blah blah blah blah...
-
-
-
- ---------------------------
-
- From: pwinkler@netcom.COM (Paul Winkler)
- Subject: Q: Eliminating clicks when playing sampled sounds
- Date: 21 Jan 92 00:24:58 GMT
- Organization: Netcom - Online Communication Services (408 241-9760 guest)
-
-
- I have tried everything I can think of, so I turn to the collective
- net.wisdom.
-
- I am writing an application that plays sounds that are stored on disk.
- The sound samples are interleaved with other data on the disk so
- SndFilePlay() is not an option for me. The data is stored 800
- bytes at a time, and the data was sampled at 8000 samples/sec (exactly).
- I am running a Mac IIci and IIfx running Sys 6.0.7.
-
- I have tried using SndDoCommand() and SndPlayDoubleBuffer() after extracting
- the data from the disk and the sound plays fine, but it has clicks in
- the audio equivalent to the 'group' rate (ie, 10 groups of 800 bytes each
- played a second == clicks a second). I am trying to get the sound to
- play without the clicks.
-
- I thought that the disk access (interrupts or the like) may have been the
- problem, but I broke out a simple application that just has a quiet pattern
- (or a one frequency tone) in the sound buffers, and there is no sound...
- except for the clicks. Usually there are clicks but sometimes not. This
- simple application is set up with SndPlayDoubleBuffer() and is almost identical
- to the example in Ch 22 of Vol VI. (I can post or forward the code to any kind
- soul who thinks they can help.)
-
- It is advertised in the tech literature that the Mac will play continuous
- sound. Am I being unreasonable to assume that it can/will play it
- 'seamlessly'? Is it related to the fact that I am using a 'non-standard'
- sample rate? (I don't think so, since I use standard rates with my
- simple program.) How does QuickTime do it? Does it just play long frames,
- so that the inter-frame click is less noticable? Am I missing something?
-
- Any ideas, suggestions, or pointers to RTFM (Read The F***ing Manual)
- via email or post will be greatly appreciated.
-
- Thanks for your time,
-
- Paul Winkler
- pwinkler@netcom.com
-
-
-
- - -------------------------
-
- From: ldo@waikato.ac.nz (Lawrence D'Oliveiro, Waikato University)
- Subject: Q: Eliminating clicks when playing sampled sounds
- Date: 21 Jan 92 03:56:46 GMT
- Organization: University of Waikato, Hamilton, New Zealand
-
- In article <1992Jan21.002458.1464pwinkler@netcom.COM>, pwinkler@netcom.COM
- (Paul Winkler) complains about clicks in playing sound data in 800-byte
- chunks on a machine with the Apple Sound Chip.
-
- As I recall, the ASC has internal buffers somewhat larger than this (more
- like 2K, I think). The clicks may be due to the chip being turned off
- when the buffer goes empty, and then turning on again for the next lot.
- Have you tried sending larger-sized chunks to SndDoCommand? Try buffering
- your data in memory and feeding it to SndDoCommand in chunks of at least 2K.
-
- I understand QuickTime plays all its sound using straight SndDoCommand calls.
-
- Lawrence D'Oliveiro fone: +64-7-856-2889
- Computer Services Dept fax: +64-7-838-4066
- University of Waikato electric mail: ldo@waikato.ac.nz
- Hamilton, New Zealand 37^ 47' 26" S, 175^ 19' 7" E, GMT+13:00
- The only thing to do with good advice is to pass it on. It is never of
- any use to oneself. -- Oscar Wilde
-
-
-
- - -------------------------
-
- From: pwinkler@netcom.COM (Paul Winkler)
- Subject: Q: Eliminating clicks when playing sampled sounds
- Date: 21 Jan 92 06:59:21 GMT
- Organization: Netcom - Online Communication Services (408 241-9760 guest)
-
- Thanks for the response, but alas, I have tried the test program with
- buffers as large as 4K, and it just makes the clicks less frequent
- (two per second versus 10 per second).
-
- Any other ideas?
-
- Thanks again
-
- Paul
- pwinkler@netcom.com
-
-
-
- - -------------------------
-
- From: REEKES@applelink.apple.com (Jim Reekes)
- Subject: Q: Eliminating clicks when playing sampled sounds
- Date: 22 Jan 92 22:13:28 GMT
- Organization: Apple Computer, Inc.
-
- In article <1992Jan21.002458.1464pwinkler@netcom.COM>, pwinkler@netcom.COM (Paul Winkler) writes:
- >
- > I am writing an application that plays sounds that are stored on disk.
- > The sound samples are interleaved with other data on the disk so
- > SndFilePlay() is not an option for me. The data is stored 800
- > bytes at a time, and the data was sampled at 8000 samples/sec (exactly).
- > I am running a Mac IIci and IIfx running Sys 6.0.7.
- >
- > I have tried using SndDoCommand() and SndPlayDoubleBuffer() after extracting
- > the data from the disk and the sound plays fine, but it has clicks in
- > the audio equivalent to the 'group' rate (ie, 10 groups of 800 bytes each
- > played a second == clicks a second). I am trying to get the sound to
- > play without the clicks.
- >
- > I thought that the disk access (interrupts or the like) may have been the
- > problem, but I broke out a simple application that just has a quiet pattern
- > (or a one frequency tone) in the sound buffers, and there is no sound...
- > except for the clicks. Usually there are clicks but sometimes not. This
- > simple application is set up with SndPlayDoubleBuffer() and is almost identical
- > to the example in Ch 22 of Vol VI. (I can post or forward the code to any kind
- > soul who thinks they can help.)
- >
- > It is advertised in the tech literature that the Mac will play continuous
- > sound. Am I being unreasonable to assume that it can/will play it
- > 'seamlessly'? Is it related to the fact that I am using a 'non-standard'
- > sample rate? (I don't think so, since I use standard rates with my
- > simple program.) How does QuickTime do it? Does it just play long frames,
- > so that the inter-frame click is less noticable? Am I missing something?
-
-
- Don't bother attempting to use SndPlayDoubleBuffer. The only
- reason SndPlayDoubleBuffer was written was to support
- SndStartFilePlay. When you call SndStartFilePlay you are using the
- double buffer routines. By using SndPlayDoubleBuffer directly,
- you're only making it harder on yourself and you'll gain nothing
- that cannot be accomplished by using SndDoCommand and the
- bufferCmd.
-
- One reason which would cause clicks when the sound chip is turned
- on or off. It's that the previous buffer of data wasn't at a zero
- crossing. When the chip is turned on, it has a problem of clicking
- if the internal buffer contains some sampled data that isn't
- silence. If you add some silence to the end of all your buffer it
- should remove the clicking. Add about 512 bytes of 0x80 to then
- end of your sampled sound. Also, you should ramp the sounds to
- silence and not just cut them off. All of this information is
- specific to the point when you call SndNewChannel and
- SndDisposeChannel.
-
- As far as using small buffers to create a continuous sound,
- QuickTime simply uses the bufferCmd to queue all of its sound
- buffers. There's no magic involved, and no undocumented secret
- tricks. The Sound Manager will attempt to butt-splice the new
- buffer to the older one to avoid unnecessary padding of silence,
- which will be necessary when rate converting to the hardware's
- output rate (22k). If there is multiple sound channels, then there
- will be some amount of gaps in the sound at buffer endings. Also,
- 800 bytes is pretty small. You should try to at least create
- buffers of 2k or larger. Other than that I'd say it's something to
- do with you data and your code. OK, well that's everything but it
- works for me so it must be something unique about your
- configuration.
-
- - -----------------------------------------------------------------
- Jim Reekes, E.O. | Macintosh Toolbox Engineering
- | Sound Manager Expert
- Apple Computer, Inc. | All opinions expressed are mine, and
- 20525 Mariani Ave. MS: 81-EQ | do not necessarily represent those
- Cupertino, CA 95014 | of my employer, Apple Computer Inc.
-
-
-
- - -------------------------
-
- From: eacj@theory.TC.Cornell.EDU (Julian Vrieslander)
- Subject: Q: Eliminating clicks when playing sampled sounds
- Date: 23 Jan 92 23:05:59 GMT
- Organization: Cornell Theory Center
-
- In article <19414@goofy.Apple.COM> REEKES@applelink.apple.com (Jim Reekes) writes:
- >One reason which would cause clicks when the sound chip is turned
- >on or off. It's that the previous buffer of data wasn't at a zero
- >crossing. When the chip is turned on, it has a problem of clicking
- >if the internal buffer contains some sampled data that isn't
- >silence. If you add some silence to the end of all your buffer it
- >should remove the clicking. Add about 512 bytes of 0x80 to then
- >end of your sampled sound. Also, you should ramp the sounds to
- >silence and not just cut them off. All of this information is
- >specific to the point when you call SndNewChannel and
- >SndDisposeChannel.
-
- This recipe will eliminate one source of clicks, but it is still possible
- to get clicks from another mechanism, at least on some Macs.
-
- I can create a long waveform containing *only* silent samples (0x80), and
- when I play it repeatedly, sometimes there will be clicks produced. If I
- use Farallon's SoundEdit, the moving waveform cursor gives a rough indication
- of where in the buffer the click is occurring. I think it is usually at
- the beginning of the buffer, but I am not certain that the clicks are
- not coming at other points. This clicking has been observed with several
- programs, including some I wrote myself. I use the simplest SoundMgr call:
- SndPlay(NULL, theSnd, TRUE).
-
- This clicking has been observed on our Mac II, and (I think) on our Mac
- Pluses. Our IIci seems to be free from this type of clicking, or much
- less prone to it. Could this be because the low level sound code is
- tailored to the ASC chip, and does not reliably leave the sound buffer clear
- on the older Macs (without ASC)?
-
- Back in the good ole days (pre-ASC, pre-Sound Mgr), I could eliminate all
- clicks by padding my waveforms to a multiple of the sound buffer size, and
- making sure to include a buffer's worth of zero samples at the end of every
- sound. But I think that this trick does not work anymore.
- --
- Julian Vrieslander
- Neurobiology & Behavior, Mudd Hall, Cornell University, Ithaca NY 14853
- INTERNET: eacj@theory.tc.cornell.edu BITNET: eacj@crnlthry
- UUCP: ..cornell!batcomputer!eacj
-
-
-
- - -------------------------
-
- From: russotto@eng.umd.edu (Matthew T. Russotto)
- Subject: Q: Eliminating clicks when playing sampled sounds
- Date: 27 Jan 92 15:24:03 GMT
- Organization: University of Maryland, College Park, College of Engineering
-
- In article <1992Jan23.230559.25390@tc.cornell.edu> eacj@theory.TC.Cornell.EDU (Julian Vrieslander) writes:
-
- >This recipe will eliminate one source of clicks, but it is still possible
- >to get clicks from another mechanism, at least on some Macs.
- >
- >I can create a long waveform containing *only* silent samples (0x80), and
- >when I play it repeatedly, sometimes there will be clicks produced. If I
- >use Farallon's SoundEdit, the moving waveform cursor gives a rough indication
- >of where in the buffer the click is occurring. I think it is usually at
- >the beginning of the buffer, but I am not certain that the clicks are
- >not coming at other points. This clicking has been observed with several
- >programs, including some I wrote myself. I use the simplest SoundMgr call:
- >SndPlay(NULL, theSnd, TRUE).
- >
- >This clicking has been observed on our Mac II, and (I think) on our Mac
- >Pluses. Our IIci seems to be free from this type of clicking, or much
- >less prone to it. Could this be because the low level sound code is
- >tailored to the ASC chip, and does not reliably leave the sound buffer clear
- >on the older Macs (without ASC)?
-
- No, it can't be that simple: The Mac II has the ASC.
- --
- Matthew T. Russotto russotto@eng.umd.edu russotto@wam.umd.edu
- Your superior intellect is no match for our puny weapons! -- The Simpsons
- Just say NO to police searches and seizures. Make them use force.
- (not responsible for bodily harm resulting from following above advice)
-
-
-
- - -------------------------
-
- From: pwinkler@netcom.COM (Paul Winkler)
- Subject: Q: Eliminating clicks when playing sampled sounds (conclusion)
- Date: 30 Jan 92 19:16:25 GMT
- Organization: Netcom - Online Communication Services (408 241-9760 guest)
-
-
- A week or so ago, I posted a request for info on how to keep
- my application that uses sampled sound from generating clicks in
- between groups of samples. My sound samples are imbedded in a disk
- file in groups of 800 bytes at a time, and was sampled at 8000
- samples/sec (10 groups per second), and I need to play the data as
- continuous sound. I am running a Mac IIci and IIfx running
- Sys 6.0.7. I develop in MPW 3.2 and Think 5.0.
-
- Thanks to the people who wrote or posted with suggestions, especially
- Jim Reekes from Apple. One more 'bravo' to the people in this group
- and to the crew at Apple who take the time to support us here on
- the 'net...
-
- I wrote the test routines (included at the end of the post for your
- inspection) to find out what was going on, and how to solve my
- problem. It plays sampled sounds and constant patterns. It
- generates a whole queue full of SoundHeaders and SndCommands
- at a time and then SndDoCommand's them in quick succession.
-
- My conclusion is, that in order to get clickless audio (for sample
- rates in the 8kHz to 11kHz range that I tested), the sizes of the
- buffers that you send to the Sound Manager in the 'bufferCmd's must
- be > 2K. The 2048 bytes is the important number. Send 2048 bytes
- or less, and you get clicks, but if you send 2049 or more bytes at
- a time, no clicks occur between groups of samples.
-
- I also discovered a strange result. If all the data samples are stored
- contiguously in a large buffer, and SoundHeaders specifying
- small buffers are just pointed along it (using the samplePtr),
- then the 2K limit does *not* apply. Moving the same data to separate
- buffers and pointing the SoundHeader's to them will have clicks if
- they are <= 2K long. Of course, if all the samples to play were
- contiguous in memory to start, it would be pretty silly to break
- them up into separate 'bufferCmds'...
-
- All this probably has to do with the 2K RAM buffer on the ASC sound
- chip, and/or the Sound Manager's handling of it.
-
- On to the code... The code below will read samples from a file, or
- generate a quiet tone (all 0x80's). It will then generate and queue
- a number of SoundHeaders and SndCommands based on the desired number of
- samples to play at a time, and the total number of samples.
-
- The code has #defines for testing a couple of the options I have
- described. The samples can be either in the 'sampleArea' field of
- the SoundHeaders, in one contiguous buffer, or in separate buffers.
-
- The routines are quick and dirty, so go easy on me please. If there is
- something you think I missed, (other than not Dispose'ing the buffers)
- let me know however :).
-
- So, my problem is solved, I just slap 3 of my 800 byte groups together
- (to make a 2400 byte buffer) before I call the Sound Manager... Hope
- this info was of help to someone... Let me know...
-
- Paul Winkler
- pwinkler@netcom.com
-
- //
- // total number of samples to play in the constant value case
- //
- #define TOTAL_BYTES (20*1024)
-
- //
- // my 8KHz rate (same results apply at the magic 11KHz too)
- //
- #define SAMP_RATE 0x1f400000L
-
- //
- // This is the number of samples in one sound buffer
- // (as specified by one SoundHeader and one SndCommand)
- //
- // Note: if buffer size is 2048 or less (for sample rates up to 11K anyway)
- // there will be audible 'clicks' between each buffer as they play
- //
- #define kBufferSize (512)
-
- //
- // another curious result:
- // if you have all of your data in one long buffer, but break the
- // playing of it up into pieces, the 2048 byte minimum above does
- // not apply
- //
- #define CONTIGUOUS 0
-
- //
- // you can put the data in the sampleArea of the SoundHeader or in
- // separate buffers.
- //
- #define DATA_IN_sampleArea 0
-
- //
- // fill a buffer with audio samples from a file, or with a quiet pattern
- //
- Ptr
- fillSampBuf(long *size)
- {
- Ptr tmp,tmp1 ;
- SFReply reply ;
- short refNum ;
- Point where ;
- long eof ;
- long i;
-
- SetPt(&where, 100,100);
- SFGetFile ( where, nil, nil, -1, nil, nil, &reply );
-
- if(reply.good) {
- //
- // user hit 'ok'... read samples from the file into the buffer
- //
- if((err = FSOpen(reply.fName,reply.vRefNum,&refNum)) != noErr)
- doNote("\pFSOpen() err",err,10);
-
- if((err = GetEOF(refNum , &eof)) != noErr)
- doNote("\pGetEOF() err",err,10) ;
-
- if((tmp = NewPtr( eof )) == nil)
- doNote("\pNewPtr() err",MemError(),10) ;
-
- if((err = FSRead(refNum,&eof,tmp)) != noErr)
- doNote("\pFSRead() error",0,10);
-
- if((err = FSClose(refNum)) != noErr)
- doNote("\pFSClose() error",0,10);
-
- *size = eof ;
- return(tmp);
- }
- else {
- //
- // user hit 'cancel', fill the buffer with quiet
- //
- tmp = tmp1 = NewPtrClear( TOTAL_BYTES ) ;
-
- for(i = 0 ; i < TOTAL_BYTES ; i++) {
- *tmp++ = 0x80 ;
- }
- *size = TOTAL_BYTES ;
- return( tmp1 ) ;
- }
- }
-
- #if DATA_IN_sampleArea
-
- typedef struct{
- SoundHeader hdr;
- char data[kBufferSize-1];
- } mySndHdr ;
-
- #else
-
- typedef struct{
- SoundHeader hdr;
- } mySndHdr ;
-
- #endif
-
- void
- doIt()
- {
- SndChannelPtr scp ;
- mySndHdr *shp ;
- SndCommand *cmd ;
- SCStatus status ;
- short i,j;
- OSErr err ;
- Ptr theData , tmp;
- long cnt,size ;
-
- /*
- * allocate the sound channel
- */
- scp = nil ;
- if((err = SndNewChannel( &scp , sampledSynth , initMono , nil )) != noErr)
- doNote("\pSndNewChannel() err",err,5) ;
-
- //
- // read the samples from a file or generate a buffer
- // full of constant values (0x80's)
- // size returns number of samples.
- //
- theData = fillSampBuf(&size) ;
-
- //
- // cnt is number of buffers to break the sound into
- // (may be leaving some samples out at the end, but who's counting?)
- //
- cnt = size / kBufferSize ;
-
- //
- // allocate the space for all the SoundHeaders and SndCommands
- //
- if((shp = (mySndHdr *) NewPtr( cnt * sizeof(mySndHdr) )) == nil) {
- doNote("\pNewPtr() err",MemError(),5) ;
- return;
- }
- if((cmd = (SndCommand *) NewPtr( cnt * sizeof(SndCommand) )) == nil) {
- doNote("\pNewPtr() err",MemError(),5) ;
- return;
- }
-
- //
- // set up all the SoundHeaders and SndCommands
- // so they can be queued in quick succession
- // (no argument that the sound queue might have
- // emptied to cause the clicking.)
- //
- for( i = 0 ; i < cnt ; i++ ) {
-
- #if DATA_IN_sampleArea
- //
- // just like it says in IM
- //
- shp[i].hdr.samplePtr = nil;
-
- //
- // put one kBufferSize of the data into the 'sampleArea'[i]
- //
- for( j = 0 ; j < kBufferSize ; j++)
- shp[i].hdr.sampleArea[j] = *theData++ ;
- #else
-
- #if CONTIGUOUS
- //
- // point subsequent 'SoundHeader's to subsequent parts
- // of the contiguous sampled data buffer
- //
- shp[i].hdr.samplePtr = theData ;
- theData += kBufferSize ;
- #else
- //
- // the other option is to allocate discontiguous buffers
- // and copy data into them
- //
- if((tmp = shp[i].hdr.samplePtr = NewPtr( kBufferSize )) == nil) {
- doNote("\pNewPtr() err",MemError(),5) ;
- return;
- }
- for( j = 0 ; j < kBufferSize ; j++)
- *tmp++ = *theData++ ;
- #endif
-
- #endif
- shp[i].hdr.length = kBufferSize ;
- shp[i].hdr.sampleRate = SAMP_RATE ;
- shp[i].hdr.loopStart = 0 ;
- shp[i].hdr.loopEnd = 0 ;
- shp[i].hdr.encode = stdSH ;
- shp[i].hdr.baseFrequency = 60 ;
-
- //
- // set up the SndCommand for this buffer of samples
- //
- cmd[i].cmd = bufferCmd ;
- cmd[i].param1 = 0 ;
- cmd[i].param2 = (long)&shp[i] ;
- }
-
- //
- // fill up the queue for the channel
- //
- for( i = 0 ; i < 127 ; i++ ) {
- if((err = SndDoCommand( scp , &cmd[i] , true)) != noErr)
- doNote("\pSndDoCommand() err",err,5) ;
- }
-
- while( !Button() ) ; // wait for the sound to finish
-
- if((err = SndDisposeChannel( scp , false )) != noErr )
- doNote("\pSndDisposeChannel() err",err,5) ;
- }
-
- /* -- eof -- */
-
-
-
- - -------------------------
-
- From: pwinkler@netcom.COM (Paul Winkler)
- Subject: Q: Eliminating clicks when playing sampled sounds (conclusion)
- Date: 30 Jan 92 19:16:25 GMT
- Organization: Netcom - Online Communication Services (408 241-9760 guest)
-
-
- A week or so ago, I posted a request for info on how to keep
- my application that uses sampled sound from generating clicks in
- between groups of samples. My sound samples are imbedded in a disk
- file in groups of 800 bytes at a time, and was sampled at 8000
- samples/sec (10 groups per second), and I need to play the data as
- continuous sound. I am running a Mac IIci and IIfx running
- Sys 6.0.7. I develop in MPW 3.2 and Think 5.0.
-
- Thanks to the people who wrote or posted with suggestions, especially
- Jim Reekes from Apple. One more 'bravo' to the people in this group
- and to the crew at Apple who take the time to support us here on
- the 'net...
-
- I wrote the test routines (included at the end of the post for your
- inspection) to find out what was going on, and how to solve my
- problem. It plays sampled sounds and constant patterns. It
- generates a whole queue full of SoundHeaders and SndCommands
- at a time and then SndDoCommand's them in quick succession.
-
- My conclusion is, that in order to get clickless audio (for sample
- rates in the 8kHz to 11kHz range that I tested), the sizes of the
- buffers that you send to the Sound Manager in the 'bufferCmd's must
- be > 2K. The 2048 bytes is the important number. Send 2048 bytes
- or less, and you get clicks, but if you send 2049 or more bytes at
- a time, no clicks occur between groups of samples.
-
- I also discovered a strange result. If all the data samples are stored
- contiguously in a large buffer, and SoundHeaders specifying
- small buffers are just pointed along it (using the samplePtr),
- then the 2K limit does *not* apply. Moving the same data to separate
- buffers and pointing the SoundHeader's to them will have clicks if
- they are <= 2K long. Of course, if all the samples to play were
- contiguous in memory to start, it would be pretty silly to break
- them up into separate 'bufferCmds'...
-
- All this probably has to do with the 2K RAM buffer on the ASC sound
- chip, and/or the Sound Manager's handling of it.
-
- On to the code... The code below will read samples from a file, or
- generate a quiet tone (all 0x80's). It will then generate and queue
- a number of SoundHeaders and SndCommands based on the desired number of
- samples to play at a time, and the total number of samples.
-
- The code has #defines for testing a couple of the options I have
- described. The samples can be either in the 'sampleArea' field of
- the SoundHeaders, in one contiguous buffer, or in separate buffers.
-
- The routines are quick and dirty, so go easy on me please. If there is
- something you think I missed, (other than not Dispose'ing the buffers)
- let me know however :).
-
- So, my problem is solved, I just slap 3 of my 800 byte groups together
- (to make a 2400 byte buffer) before I call the Sound Manager... Hope
- this info was of help to someone... Let me know...
-
- Paul Winkler
- pwinkler@netcom.com
-
- //
- // total number of samples to play in the constant value case
- //
- #define TOTAL_BYTES (20*1024)
-
- //
- // my 8KHz rate (same results apply at the magic 11KHz too)
- //
- #define SAMP_RATE 0x1f400000L
-
- //
- // This is the number of samples in one sound buffer
- // (as specified by one SoundHeader and one SndCommand)
- //
- // Note: if buffer size is 2048 or less (for sample rates up to 11K anyway)
- // there will be audible 'clicks' between each buffer as they play
- //
- #define kBufferSize (512)
-
- //
- // another curious result:
- // if you have all of your data in one long buffer, but break the
- // playing of it up into pieces, the 2048 byte minimum above does
- // not apply
- //
- #define CONTIGUOUS 0
-
- //
- // you can put the data in the sampleArea of the SoundHeader or in
- // separate buffers.
- //
- #define DATA_IN_sampleArea 0
-
- //
- // fill a buffer with audio samples from a file, or with a quiet pattern
- //
- Ptr
- fillSampBuf(long *size)
- {
- Ptr tmp,tmp1 ;
- SFReply reply ;
- short refNum ;
- Point where ;
- long eof ;
- long i;
-
- SetPt(&where, 100,100);
- SFGetFile ( where, nil, nil, -1, nil, nil, &reply );
-
- if(reply.good) {
- //
- // user hit 'ok'... read samples from the file into the buffer
- //
- if((err = FSOpen(reply.fName,reply.vRefNum,&refNum)) != noErr)
- doNote("\pFSOpen() err",err,10);
-
- if((err = GetEOF(refNum , &eof)) != noErr)
- doNote("\pGetEOF() err",err,10) ;
-
- if((tmp = NewPtr( eof )) == nil)
- doNote("\pNewPtr() err",MemError(),10) ;
-
- if((err = FSRead(refNum,&eof,tmp)) != noErr)
- doNote("\pFSRead() error",0,10);
-
- if((err = FSClose(refNum)) != noErr)
- doNote("\pFSClose() error",0,10);
-
- *size = eof ;
- return(tmp);
- }
- else {
- //
- // user hit 'cancel', fill the buffer with quiet
- //
- tmp = tmp1 = NewPtrClear( TOTAL_BYTES ) ;
-
- for(i = 0 ; i < TOTAL_BYTES ; i++) {
- *tmp++ = 0x80 ;
- }
- *size = TOTAL_BYTES ;
- return( tmp1 ) ;
- }
- }
-
- #if DATA_IN_sampleArea
-
- typedef struct{
- SoundHeader hdr;
- char data[kBufferSize-1];
- } mySndHdr ;
-
- #else
-
- typedef struct{
- SoundHeader hdr;
- } mySndHdr ;
-
- #endif
-
- void
- doIt()
- {
- SndChannelPtr scp ;
- mySndHdr *shp ;
- SndCommand *cmd ;
- SCStatus status ;
- short i,j;
- OSErr err ;
- Ptr theData , tmp;
- long cnt,size ;
-
- /*
- * allocate the sound channel
- */
- scp = nil ;
- if((err = SndNewChannel( &scp , sampledSynth , initMono , nil )) != noErr)
- doNote("\pSndNewChannel() err",err,5) ;
-
- //
- // read the samples from a file or generate a buffer
- // full of constant values (0x80's)
- // size returns number of samples.
- //
- theData = fillSampBuf(&size) ;
-
- //
- // cnt is number of buffers to break the sound into
- // (may be leaving some samples out at the end, but who's counting?)
- //
- cnt = size / kBufferSize ;
-
- //
- // allocate the space for all the SoundHeaders and SndCommands
- //
- if((shp = (mySndHdr *) NewPtr( cnt * sizeof(mySndHdr) )) == nil) {
- doNote("\pNewPtr() err",MemError(),5) ;
- return;
- }
- if((cmd = (SndCommand *) NewPtr( cnt * sizeof(SndCommand) )) == nil) {
- doNote("\pNewPtr() err",MemError(),5) ;
- return;
- }
-
- //
- // set up all the SoundHeaders and SndCommands
- // so they can be queued in quick succession
- // (no argument that the sound queue might have
- // emptied to cause the clicking.)
- //
- for( i = 0 ; i < cnt ; i++ ) {
-
- #if DATA_IN_sampleArea
- //
- // just like it says in IM
- //
- shp[i].hdr.samplePtr = nil;
-
- //
- // put one kBufferSize of the data into the 'sampleArea'[i]
- //
- for( j = 0 ; j < kBufferSize ; j++)
- shp[i].hdr.sampleArea[j] = *theData++ ;
- #else
-
- #if CONTIGUOUS
- //
- // point subsequent 'SoundHeader's to subsequent parts
- // of the contiguous sampled data buffer
- //
- shp[i].hdr.samplePtr = theData ;
- theData += kBufferSize ;
- #else
- //
- // the other option is to allocate discontiguous buffers
- // and copy data into them
- //
- if((tmp = shp[i].hdr.samplePtr = NewPtr( kBufferSize )) == nil) {
- doNote("\pNewPtr() err",MemError(),5) ;
- return;
- }
- for( j = 0 ; j < kBufferSize ; j++)
- *tmp++ = *theData++ ;
- #endif
-
- #endif
- shp[i].hdr.length = kBufferSize ;
- shp[i].hdr.sampleRate = SAMP_RATE ;
- shp[i].hdr.loopStart = 0 ;
- shp[i].hdr.loopEnd = 0 ;
- shp[i].hdr.encode = stdSH ;
- shp[i].hdr.baseFrequency = 60 ;
-
- //
- // set up the SndCommand for this buffer of samples
- //
- cmd[i].cmd = bufferCmd ;
- cmd[i].param1 = 0 ;
- cmd[i].param2 = (long)&shp[i] ;
- }
-
- //
- // fill up the queue for the channel
- //
- for( i = 0 ; i < 127 ; i++ ) {
- if((err = SndDoCommand( scp , &cmd[i] , true)) != noErr)
- doNote("\pSndDoCommand() err",err,5) ;
- }
-
- while( !Button() ) ; // wait for the sound to finish
-
- if((err = SndDisposeChannel( scp , false )) != noErr )
- doNote("\pSndDisposeChannel() err",err,5) ;
- }
-
- /* -- eof -- */
-
-
-
- ---------------------------
-
- From: williamu@extro.ucc.su.OZ.AU (William Uther)
- Subject: Software Locking for Word 4D
- Date: 18 Feb 92 04:09:06 GMT
- Organization: Uni Computing Service, Uni of Sydney, Australia
-
- Hi,
- I am in charge on two Mac SE's at college with which most people use word 4.
- The college owns some copies of word to use with these mac's, but the Mac's
- are unsupervised and there is a problem with the disks being stolen or trashed.
- The best solution for this would be to give each user there own copies of the
- system and word disks, but this would breach copywrite.
- I was wondering if it would be possable to put a small piece of code into
- the word programs which checked the serial number of the mac it was running
- on and would exit if it wasn't one of the allowed mac's. This probably breaches
- the letter of the licence aggreement, but it is to preserve the spirit of the
- aggreement and stop copies.
- Anyone have any idea's. Maybe a writer of virus's could do something useful
- and help out??
- Thanks in advance
- \x/ill :-}
-
-
-
- - -------------------------
-
- From: Carl.Constantine@BCSystems.GOV.BC.CA
- Subject: Software Locking for Word 4D
- Date: 19 Feb 92 23:59:53 GMT
- Organization: BC Systems Corporation
-
- In article <1992Feb18.040906.3763@ucc.su.OZ.AU>, williamu@extro.ucc.su.OZ.AU (William Uther) writes:
- > Hi,
- > I am in charge on two Mac SE's at college with which most people use word 4.
- > The college owns some copies of word to use with these mac's, but the Mac's
- > are unsupervised and there is a problem with the disks being stolen or trashed.
- > The best solution for this would be to give each user there own copies of the
- > system and word disks, but this would breach copywrite.
- > I was wondering if it would be possable to put a small piece of code into
- > the word programs which checked the serial number of the mac it was running
- > on and would exit if it wasn't one of the allowed mac's. This probably breaches
- > the letter of the licence aggreement, but it is to preserve the spirit of the
- > aggreement and stop copies.
- > Anyone have any idea's. Maybe a writer of virus's could do something useful
- > and help out??
- > Thanks in advance
- > \x/ill :-}
-
- Actually, you could write this program yourself, use ResEdit to make Word 4
- invisible on the distrutable diskette and give your program the creater types
- etc of Word. This actually prevents users from copying Word to becase they get
- your probram and not the _invisible_ Word file. This is what we use to do at
- UVic (University of Victoria in British Columbia) before the Server went in.
- good luck.
- --
- Carl.Constantine@BCSystems.gov.bc.ca
- Victoria, British Columbia, Canada
-
-
-
- ---------------------------
-
- From: dmmg1176@uxa.cso.uiuc.edu (David M Marcovitz)
- Subject: DirectorOwner owns DialogDirector and crashes (Think C/TCL)
- Date: 19 Feb 92 04:43:24 GMT
- Organization: University of Illinois at Urbana
-
- I am trying to implement an application in Think C 5.0.2 and TCL
- 1.1.2. I want my documents to control modal dialogs instead of
- regular windows. Everything works fine, except when I dispose of the
- dialog, I crash.
-
- I traced it throught the debugger, and hear is what happens:
-
- (1) CDocument is a subclass of CDirectorOwner.
- (2) CDialogDirector is a subclass of CDirector.
- (3) When myDialogDirector is initialized with myDocument as its
- supervisor, myDialogDirector is installed on the list of directors
- owned by myDocument (this is done in the IDirector() method).
- (4) myDialogDirector is the only director owned by myDocument.
- (5) When I dispose of myDialogDirector, myDocument's list of directors
- that it owns becomes empty.
- (6) This happens just before myDialogDirector actual gets disposed.
- (7) Also before myDialogDirector gets disposed, myDocument finds its
- list of directors empty, so being the good CDirectorOwner that it
- is (with no more directors to look after), it disposes of itself.
- (8) Now, myDialogDirector is about to actually dispose of itself, but
- itsSupervisor (myDocument) has just been disposed.
- (9) When myDialogDirector actually disposes of itself, it finds that
- it is the gopher. Therefore, it makes itsSupervisor the gopher.
- itsSupervisor->BecomeGopher(TRUE)
- (10) However, itsSupervisor (i.e., myDocument) was already disposed
- (in step 7) so BANG!!!! The program crashes.
-
- This was all done with TCL code. I just asked for myDialog to be
- supervised by myDocument. Then, later, I asked for myDialog to be
- disposed. (If I don't dispose of myDialog, TCL will do it for me and
- crash anyway.) This seems to be a bug in TCL. Is it? If it isn't,
- what am I doing wrong?
-
- I can work around this problem by installing a dummyDirector with
- myDocument as itsSupervisor. This means that myDocument never finds
- its list directors that it owns empty so it doesn't dispose of itself.
- This is really a kluge so there must be a better way. What is it?
-
- Thanks for your help.
- --
- David M. Marcovitz | internet: marcovitz@uiuc.edu
- Computer-based Education Research Lab | dmmg1176@uxa.cso.uiuc.edu
- University of Illinois | novanet: marco / cca / nova
-
-
-
- - -------------------------
-
- From: dmmg1176@uxa.cso.uiuc.edu (David M Marcovitz)
- Subject: DirectorOwner owns DialogDirector and crashes (Think C/TCL)
- Organization: University of Illinois at Urbana
- Date: Wed, 19 Feb 1992 17:56:36 GMT
-
- dmmg1176@uxa.cso.uiuc.edu (David M Marcovitz) writes:
-
- >I am trying to implement an application in Think C 5.0.2 and TCL
- >1.1.2. I want my documents to control modal dialogs instead of
- >regular windows. Everything works fine, except when I dispose of the
- >dialog, I crash.
-
- >...stuff deleted...
-
- >I can work around this problem by installing a dummyDirector with
- >myDocument as itsSupervisor. This means that myDocument never finds
- >its list directors that it owns empty so it doesn't dispose of itself.
- >This is really a kluge so there must be a better way. What is it?
-
- Another thing that seems to work is if I make myDocument the gopher
- before disposing of myDialogDirector. Then, myDialogDirector doesn't
- need to make myDocument (itsSupervisor) gopher just before disposing
- of itself. This is less of a kluge, but there still must be a better
- way.
-
- --
- David M. Marcovitz | internet: marcovitz@uiuc.edu
- Computer-based Education Research Lab | dmmg1176@uxa.cso.uiuc.edu
- University of Illinois | novanet: marco / cca / nova
-
-
-
- - -------------------------
-
- From: rla20@duts.ccc.amdahl.com (Roger Allen)
- Subject: DirectorOwner owns DialogDirector and crashes (Think C/TCL)
- Date: 19 Feb 92 19:37:39 GMT
- Organization: Amdahl Corporation, Sunnyvale CA
-
- In article <1992Feb19.175636.19560@ux1.cso.uiuc.edu> dmmg1176@uxa.cso.uiuc.edu (David M Marcovitz) writes:
- >dmmg1176@uxa.cso.uiuc.edu (David M Marcovitz) writes:
- >
- >>I am trying to implement an application in Think C 5.0.2 and TCL
- >>1.1.2. I want my documents to control modal dialogs instead of
- >>regular windows. Everything works fine, except when I dispose of the
- >>dialog, I crash.
- >
- ...stuff deleted...
- >Another thing that seems to work is if I make myDocument the gopher
- >before disposing of myDialogDirector. Then, myDialogDirector doesn't
- >need to make myDocument (itsSupervisor) gopher just before disposing
- >of itself. This is less of a kluge, but there still must be a better
- >way.
-
- Why is this a kludge? Seems like the document should keep track of its
- gophers. Where should the gopher point to after you get rid of the
- current object it is pointing to? Doesn`t seem like a kludge--seems
- like proper housekeeping.
-
- Just my 2cents.
- --
- > Roger Allen | All the opinions expressed are my <
- > Amdahl Computer Development | own and are not Amdahl's. <
- > rla20@cd.amdahl.com | ------They paid me to say that------- <
-
-
-
- - -------------------------
-
- From: dmmg1176@uxa.cso.uiuc.edu (David M Marcovitz)
- Subject: DirectorOwner owns DialogDirector and crashes (Think C/TCL)
- Date: 19 Feb 92 22:52:53 GMT
- Organization: University of Illinois at Urbana
-
- rla20@duts.ccc.amdahl.com (Roger Allen) writes:
- >Why is this a kludge? Seems like the document should keep track of its
- >gophers. Where should the gopher point to after you get rid of the
- >current object it is pointing to? Doesn`t seem like a kludge--seems
- >like proper housekeeping.
-
- The reason this is a kludge is that TCL does this for me, sort of.
- When TCL disposes of myDialogDirector, it checks to see if it is the
- gopher, and if it is, it makes itsSupervisor (myDocument) the gopher.
- Unfortunately, it has already disposed of myDocument. It shouldn't
- dispose of myDocument until AFTER it finishes disposing of
- myDialogDirector.
-
- --
- David M. Marcovitz | internet: marcovitz@uiuc.edu
- Computer-based Education Research Lab | dmmg1176@uxa.cso.uiuc.edu
- University of Illinois | novanet: marco / cca / nova
-
-
-
- ---------------------------
-
- End of C.S.M.P. Digest
- **********************
-